//== SAGITTARIUS ============================================================================

//== BEGINNING OF CODE ===============================================================

#include "sagittarius/core/SagittariusCore.h"
#include "sagittarius/builtins/modules/io.h"
#include "sagittarius/io/io.h"
#include "sagittarius/backend/llvm/llvm_interf.h"
#include "sagittarius/backend/llvm/llvm_types.h"
#include <string.h>
#include <malloc.h>

//LLVM
#include "llvm/Support/DataTypes.h"
#include "llvm/DerivedTypes.h"
#include "llvm/IRBuilder.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Analysis/Verifier.h"

#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_os_ostream.h"

using namespace Sagittarius;

void sg_mod_io_generate(sg_module* mod, sg_mod_io_members* members) {
    SG_WRITE(2, "sg_mod_io_generate\n");
    
    llvm::Module* lmod = new llvm::Module("mod_io", llvm::getGlobalContext());
    
    LLVM_Types* types = getLLVMTypes();
    
    std::vector<llvm::Type*> args;
    
    args.clear();
    args.push_back(types->pvoid);
    args.push_back(types->pval);
    llvm::FunctionType* f_mod_io_fprintln_tp = llvm::FunctionType::get(types->pval, args, false);
    llvm::Function* f_mod_io_fprintln = (llvm::Function*)lmod->getOrInsertFunction("__f_mod_io_fprintln", f_mod_io_fprintln_tp);
    
    llvm::ExecutionEngine* e = llvmi->getee();
    e->addGlobalMapping(f_mod_io_fprintln, (void*)(sg_mod_io_fprintln));
    
    //LLVM_Util* util = getLLVMUtil();
    
    //util->storeFP(members->f_println, (void*)(sg_mod_io_fprintln));
    
    //members->f_println->f = (void*)(sg_mod_io_fprintln);
    members->f_println->f = NULL;
}

